package org.eclipseuseradmin.internal.ui.security;

import java.net.URL;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import org.eclipse.equinox.security.auth.ILoginContext;
import org.eclipse.equinox.security.auth.ILoginContextListener;
import org.eclipse.equinox.security.auth.LoginContextFactory;
import org.eclipse.rwt.RWT;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.services.ISourceProviderService;

public class RapLoginContext implements ILoginContext {

	private String name;

	private URL conf;
	
	private SourceProviderListener sourceProviderListener;

	public RapLoginContext(String name, URL conf) throws LoginException {

		this.name = name;
		this.conf = conf;
		this.sourceProviderListener = new SourceProviderListener();
	}

	public Subject getSubject() throws LoginException {
		return getSessionScopeLoginContext().getSubject();
	}

	public void login() throws LoginException {
		getSessionScopeLoginContext().login();
	}

	public void logout() throws LoginException {
		getSessionScopeLoginContext().logout();
	}

	public LoginContext getLoginContext() throws LoginException {
		return getSessionScopeLoginContext().getLoginContext();
	}

	public void registerListener(ILoginContextListener listener) {
		getSessionScopeLoginContext().registerListener(listener);
	}

	public void unregisterListener(ILoginContextListener listener) {
		getSessionScopeLoginContext().unregisterListener(listener);
	}

	private ILoginContext getSessionScopeLoginContext() {

		ILoginContext loginContext = (ILoginContext) RWT.getSessionStore()
				.getAttribute(ILoginContext.class.getName());
		if (loginContext == null) {
			loginContext = LoginContextFactory.createContext(name, conf);
			loginContext.registerListener(sourceProviderListener);
			RWT.getSessionStore().setAttribute(ILoginContext.class.getName(),
					loginContext);
		}
		return loginContext;
	}
	
	private class SourceProviderListener implements ILoginContextListener {

		public void onLoginFinish(Subject subject, LoginException loginException) {
	
			if (loginException != null) {
				return;
			}
			
			getUserAdminSourceProvider().setSubject(subject);
		}

		public void onLoginStart(Subject subject) {
		}

		public void onLogoutFinish(Subject subject,
				LoginException logoutException) {
			
			if (logoutException != null) {
				return;
			}
			
			getUserAdminSourceProvider().setSubject(null);
		}

		public void onLogoutStart(Subject subject) {
		}
		
		private UserAdminSourceProvider getUserAdminSourceProvider() {

			IWorkbench workbench = (IWorkbench) RWT.getSessionStore().getAttribute(
					"com_w4t_session_singleton_org.eclipse.ui.internal.Workbench");
			ISourceProviderService sourceProviderService = (ISourceProviderService) workbench
					.getService(ISourceProviderService.class);
			return (UserAdminSourceProvider) sourceProviderService
					.getSourceProvider(UserAdminSourceProvider.ROLES);
		}
	} 
}
